package com.fc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fc.dao.ShoppingCarMapper;
import com.fc.entity.Category;
import com.fc.entity.Product;
import com.fc.entity.ShoppingCar;
import com.fc.entity.input.DeleteBatchInput;
import com.fc.entity.input.ProductQueryInput;
import com.fc.entity.input.ShoppingCarInput;
import com.fc.entity.input.ShoppingCarQueryInput;
import com.fc.entity.output.ProductOutput;
import com.fc.entity.output.ShoppingCarOutput;
import com.fc.entity.query.PageQuery;
import com.fc.enums.DelFlagEnum;
import com.fc.service.ProductService;
import com.fc.service.ShoppingCarService;
import com.fc.service.UserService;
import com.fc.service.baseService.impl.BaseServiceImpl;
import com.fc.service.baseService.impl.ThreadLocalService;
import com.fc.utils.ParseWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 购物车 服务实现类
 * </p>
 *
 * @author
 * @since 2024-11-07
 */
@Service
@RequiredArgsConstructor
public class ShoppingCarServiceImpl extends BaseServiceImpl<ShoppingCarMapper, ShoppingCar> implements ShoppingCarService {

    private final ThreadLocalService threadLocalService;

    private final UserService userService;

    private final ProductService productService;

    @Override
    public boolean add(ShoppingCarInput input) {
        input.setId(null);
        String userName = threadLocalService.getThreadLocal();
        ShoppingCar shoppingCar = BeanUtil.copyProperties(input, ShoppingCar.class);
        //todo 写死user，后续完善登录补充
        /*User user = userService.getUserByName(userName);
        shoppingCar.setUserId(user.getId());*/
        shoppingCar.setUserId(0L);
        return savePre(shoppingCar);
    }

    @Override
    public IPage<ShoppingCarOutput> getPage(PageQuery query, ShoppingCarQueryInput input) {
        QueryWrapper<ShoppingCar> wrapper = ParseWrapper.parseWrap(input, ShoppingCar.class);
        wrapper.lambda().eq(ShoppingCar::getDelFlag, DelFlagEnum.NORMAL);
        IPage<ShoppingCar> page = page(Page.of(query.getPageNumber(), query.getPageSize()), wrapper);
        List<ShoppingCar> records = page.getRecords();
        Map<Long, Long> carProMap = records.stream().collect(Collectors.toMap(ShoppingCar::getId, ShoppingCar::getProductId));
        List<Long> proIds = records.stream().map(ShoppingCar::getProductId).toList();
        List<Product> productList = productService.listByIds(proIds);
        Map<Long, List<Category>> proCatMap = productService.getCategories(proIds);
        List<ProductOutput> productOutputs = BeanUtil.copyToList(productList, ProductOutput.class);
        productOutputs.forEach(p -> {
            p.setCategories(proCatMap.get(p.getId()));
        });
        Map<Long, ProductOutput> outputMap = productOutputs.stream().collect(Collectors.toMap(ProductOutput::getId, o -> o));
        IPage<ShoppingCarOutput> outputIPage = page.convert(p -> BeanUtil.copyProperties(p, ShoppingCarOutput.class));
        outputIPage.getRecords().forEach(c -> c.setProductOutput(outputMap.get(carProMap.get(c.getId()))));
        return outputIPage;
    }

    @Override
    public boolean renew(ShoppingCarInput input) {
        return false;
    }

    @Override
    public boolean del(DeleteBatchInput input) {
        List<Long> ids = list(new LambdaQueryWrapper<ShoppingCar>()
                .eq(ShoppingCar::getDelFlag, DelFlagEnum.NORMAL)
                .in(ShoppingCar::getProductId, input.getIds()))
                .stream()
                .map(ShoppingCar::getId)
                .toList();
        return removeBatchByIds(ids);
    }

    @Override
    public boolean addNum(ShoppingCarInput input) {
        //todo 写死user，后续完善登录补充
        //User user = userService.getUserByName(userName);
        ShoppingCar shoppingCar = getOne(new LambdaQueryWrapper<ShoppingCar>()
                .eq(ShoppingCar::getDelFlag, DelFlagEnum.NORMAL)
                //.eq(ShoppingCar::getUserId,user.getId())
                .eq(ShoppingCar::getUserId, 0L)
                .eq(ShoppingCar::getId, input.getId()));
        shoppingCar.setProductNum(input.getIsAdd() ? shoppingCar.getProductNum() + 1 : shoppingCar.getProductNum() - 1);
        return updateByIdPre(shoppingCar);
    }
}
